/*
 * NeighborPacket.java
 *
 * Created on April 15, 2008, 9:53 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.sunspotworld.mydatawrappers;

import com.sun.spot.peripheral.Spot;
import java.io.IOException;
import org.sunspotworld.sensortasks.TimeKeeper;
import com.sun.spot.util.IEEEAddress;
import java.util.Date;

/**
 * A data wrapper class to encapsulate information about received radio beacons and methods to transmit, receive and record this information
 * @author Douglas McClusky
 */
public final class NeighborPacket extends TrackingPacket {
    private long[] addresses = new long[15];
    int index;
    public static final String HEADER = "Date\tTime\tNode\tNeighbors";
    
    /*
    protected NeighborPacket(byte[] b) {
        super.readSign(b);
        int temp = super.signSize;
        super.timestamp = super.byteArrayToLong(b, temp);
        temp += 8;
        index = super.byteArrayToInt(b, temp);
        temp += 4;
        addresses = new long[index];
        for (int i=0; i<index; i++) {
            addresses[i] = super.byteArrayToLong(b, temp);
            temp += 8;
        }
    } //*/
    
    protected NeighborPacket(byte[] b, int i) {
        super.readSign(b, i);
        super.type = super.NEIGHBOR_PACKET;
        int temp = super.SIGN_SIZE + i;
        index = super.byteArrayToInt(b, temp);
        //System.out.println(index);
        temp += 4;
        addresses = new long[index];
        for (int j=0; j<index; j++) {
            addresses[j] = super.byteArrayToLong(b, temp);
            //System.out.println("address " + j + " " + addresses[j]);
            temp += 8;
        }
    }
    
    /**
     * Creates a new instance of NeighborPacket whose super.timestamp is filled from TimeKeeper on generation
     */
    public NeighborPacket() {
        super.type = super.NEIGHBOR_PACKET;
        super.timestamp = TimeKeeper.getInstance().currentTimeMillis();
        super.senderAddress=Spot.getInstance().getRadioPolicyManager().getIEEEAddress();
        index = 0;
    }
    
    /**
     * Add the IEEE address of an overheard radio beacon to this packet
     * @param address
     */
    public void addAddress(long address) {
        addresses[index]=address;
        index++;
        if (index >= addresses.length-5) {
            doubleSize();
        }
    }
    
    public long[] getAddresses() {
        if (index == 0) {
            return null;
        }
        long[] addr = new long[index];
        for (int i=0; i<index; i++) {
            addr[i] = addresses[i];
        }
        return addr;
    }
    
    private void doubleSize() {
        long[] temp = new long[addresses.length*2];
        for (int i=0; i<index; i++) {
            temp[i] = addresses[i];
        }
        addresses = temp;
    }
    
    /**
     * Determines whether there are any overheard radio beacons recorded in this packet
     * @return whether packet is empty
     */
    public boolean isEmpty() {
        return index==0;
    }
    
    /**
     * A String representation of this NeighborPacket for writing records
     * @return the packet's information in comma-delimited format
     */
    public String printEntryLine() {
        Date time = new Date(super.timestamp);
        //SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd '\t' HH:mm:ss.SSS");
        String line = time + "\t" + new IEEEAddress(super.senderAddress).asDottedHex() + "\t";
        for (int i = 0; i< index; i++) {
            line = line + new IEEEAddress(addresses[i]).asDottedHex() + "\t";
        }
        return line;
    }
    
    /**
     * A method to track the size of this packet for keeping track of Radiogram space use
     * @return the space used by writeToRadiogram in bytes.
     */
    public int getSize() {
        return TrackingPacket.SIGN_SIZE + 4 + 8*index; // index * address longs + int index + header size
    }
    
    /**
     * Return the constant header for the type of packet
     * @return the record header for this type of packet
     */
    public static String printRecordHeader() {
        return HEADER;
    }

    public byte[] toByteArray() {
        byte[] b = new byte[getSize()];
        int i;
        super.sign(b);
        int temp = super.SIGN_SIZE;
        byte[] tempArray = super.intToByteArray(index);
        //System.out.println(super.byteArrayToInt(tempArray, 0));
        for (i = 0; i < tempArray.length; i++) {
            b[temp] = tempArray[i];
            temp++;
        }
        //System.out.println(super.byteArrayToInt(b, temp-4));
        for (int j = 0; j < index; j++) {
            //System.out.println("address " + j + " " + addresses[j]);
            tempArray = super.longToByteArray(addresses[j]);
            //System.out.println(super.byteArrayToLong(tempArray, 0));
            for (i = 0; i < tempArray.length; i++) {
                b[temp] = tempArray[i];
                temp++;
            }
            //System.out.println(super.byteArrayToLong(b, temp-8));
        }
        //*
        try {
            System.out.println("this\t" + this.printEntryLine());
            System.out.println("new\t" + new NeighborPacket(b, 0).printEntryLine());
            System.out.println("factory\t" + TrackingPacketFactory.getInstance().constructDataWrapper(b).printEntryLine());
        } catch (IOException ex) {
            ex.printStackTrace();
        } //*/
        return b;
    }
}
